package cn.edu.tju.elm.service.Impl;

import cn.edu.tju.core.model.Authority;
import cn.edu.tju.core.model.User;
import cn.edu.tju.elm.model.*;
import cn.edu.tju.elm.repository.*;
import cn.edu.tju.elm.service.OrderService;
import cn.edu.tju.core.security.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;
import java.util.Optional;

import cn.edu.tju.elm.service.BusinessService;
import cn.edu.tju.elm.model.OrderDetailet;


@Service
public class OrderServiceImpl implements OrderService {

    private final OrderRepository orderRepository;
    private final OrderDetailetRepository orderDetailetRepository;

    @Autowired
    public OrderServiceImpl(OrderRepository orderRepository,OrderDetailetRepository orderDetailetRepository) { // 修改构造函数
        this.orderRepository = orderRepository;
        this.orderDetailetRepository = orderDetailetRepository; // 新增初始化
    }
    @Autowired
    private CartRepository cartRepository;

    @Autowired
    private UserService userService;

    @Autowired
    private DeliveryAddressRepository  deliveryAddressRepository;

    @Autowired
    private BusinessService businessService;


    private BigDecimal calculateTotalAmount(List<Cart> cartItems) {
        return cartItems.stream()
                .map(item -> item.getFood().getFoodPrice().multiply(BigDecimal.valueOf(item.getQuantity())))
                .reduce(BigDecimal.ZERO, BigDecimal::add);
    }


    //查询营业订单
    public List<Order> findByBusinessId(Long businessId) {
        // 获取当前用户
        User currentUser = userService.getUserWithAuthorities().orElse(null);
        if (currentUser == null) {
            return Collections.emptyList();
        }

        // 检查是否是管理员或该商家的所有者
        boolean isAdmin = currentUser.getAuthorities().stream()
                .anyMatch(authority -> "ADMIN".equals(authority.getName()));

        // 检查当前用户是否是商家的所有者
        boolean isBusinessOwner = false;
        if (!isAdmin) {
            Optional<Business> businessOptional = businessService.findById(businessId);
            if (businessOptional.isPresent()) {
                Business business = businessOptional.get();
                isBusinessOwner = business.getBusinessOwner().getId().equals(currentUser.getId());
            }
        }

        // 如果是管理员或商家所有者，返回订单列表
        if (isAdmin || isBusinessOwner) {
            return orderRepository.findByBusinessIdOrderByOrderDateDesc(businessId);
        }

        return Collections.emptyList();
    }


    //根据orderID查询订单详情
    public Optional<Order> findById(Long id) {
        // 获取当前用户
        User currentUser = userService.getUserWithAuthorities().orElse(null);
        if (currentUser == null) {
            return Optional.empty();
        }

        // 检查是否是管理员
        boolean isAdmin = false;
        for (Authority authority : currentUser.getAuthorities()) {
            if (authority.getName().equals("ADMIN")) {
                isAdmin = true;
                break;
            }
        }

        Optional<Order> orderOptional = orderRepository.findById(id);
        if (!orderOptional.isPresent()) {
            return Optional.empty();
        }

        Order order = orderOptional.get();

        // 如果是管理员，可以查询任何订单
        if (isAdmin) {
            return orderOptional;
        }

        // 检查订单是否属于当前用户（作为顾客）
        if (order.getCustomer() != null &&
                order.getCustomer().getId().equals(currentUser.getId())) {
            return orderOptional;
        }


        return Optional.empty();
    }

    //查询消费订单
    @Override
    public List<Order> findByCustomerId(Long userId) {
        // 获取当前用户
        User currentUser = userService.getUserWithAuthorities().orElse(null);
        if (currentUser == null) {
            return Collections.emptyList();
        }

        // 检查是否是管理员
        boolean isAdmin = currentUser.getAuthorities().stream()
                .anyMatch(authority -> "ADMIN".equals(authority.getName()));

        // 如果是管理员或者查询的是自己的订单，返回订单列表
        if (isAdmin || currentUser.getId().equals(userId)) {
            return orderRepository.findByCustomerIdOrderByOrderDateDesc(userId);
        }

        return Collections.emptyList();
    }


    @Override
    public List<OrderDetailet> findOrderDetailetById(Long orderId) {
        // 获取当前用户
        User currentUser = userService.getUserWithAuthorities().orElse(null);
        if (currentUser == null) {
            return Collections.emptyList();
        }

        // 检查是否是管理员
        boolean isAdmin = currentUser.getAuthorities().stream()
                .anyMatch(authority -> "ADMIN".equals(authority.getName()));

        // 先获取订单
        Optional<Order> orderOptional = orderRepository.findById(orderId);
        if (!orderOptional.isPresent()) {
            return Collections.emptyList();
        }

        Order order = orderOptional.get();

        // 权限检查：管理员、订单所属用户或商家所有者可以查看
        boolean hasPermission = isAdmin;

        // 检查是否是订单所属用户
        if (!hasPermission && order.getCustomer() != null) {
            hasPermission = order.getCustomer().getId().equals(currentUser.getId());
        }

        // 检查是否是商家所有者
        if (!hasPermission && order.getBusiness() != null && order.getBusiness().getBusinessOwner() != null) {
            hasPermission = order.getBusiness().getBusinessOwner().getId().equals(currentUser.getId());
        }

        if (hasPermission) {
            // 使用Spring Data JPA的命名查询方式获取订单详情
            return orderDetailetRepository.findByOrderId(orderId);
        }

        return Collections.emptyList();
    }

    @Override
    @Transactional
    public Order updateOrderState(Long orderId, Integer orderState) {
        // 获取当前用户
        User currentUser = userService.getUserWithAuthorities().orElse(null);
        if (currentUser == null) {
            throw new RuntimeException("用户未登录");
        }

        // 检查是否是管理员
        boolean isAdmin = currentUser.getAuthorities().stream()
                .anyMatch(authority -> "ADMIN".equals(authority.getName()));

        // 先获取订单
        Optional<Order> orderOptional = orderRepository.findById(orderId);
        if (!orderOptional.isPresent()) {
            throw new RuntimeException("订单不存在");

        }

        Order order = orderOptional.get();

        // 权限检查：管理员、订单所属用户或商家所有者可以更新
        boolean hasPermission = isAdmin;

        // 检查是否是订单所属用户
        if (!hasPermission && order.getCustomer() != null) {
            hasPermission = order.getCustomer().getId().equals(currentUser.getId());
        }

        // 检查是否是商家所有者
        if (!hasPermission && order.getBusiness() != null && order.getBusiness().getBusinessOwner() != null) {
            hasPermission = order.getBusiness().getBusinessOwner().getId().equals(currentUser.getId());
        }

        if (!hasPermission) {
            throw new RuntimeException("没有权限更新此订单状态");
        }

        // 验证订单状态值（0-待支付，1-已支付，2-已取消，3-待出餐，4-配送中，5-已完成，6-已退款）
        if (orderState < 0 || orderState > 6) {
            throw new RuntimeException("无效的订单状态");
        }

        // 更新订单状态
        order.setOrderState(orderState);
        order.setUpdateTime(LocalDateTime.now());
        order.setUpdater(currentUser.getId());

        return orderRepository.save(order);
    }


    @Override
    @Transactional
    public Order createOrderFromCart(Long userId, Long businessId, Order order) {
        // 1. 获取某商家用户购物车中的所有商品
        List<Cart> cartItems = cartRepository.findByCustomerIdAndBusinessId(userId, businessId);
        if (cartItems == null || cartItems.isEmpty()) {
            throw new RuntimeException("购物车为空，无法创建订单");
        }

        // 2. 验证配送地址是否属于该用户
        if (order.getDeliveryAddress() == null || order.getDeliveryAddress().getId() == null) {
            throw new RuntimeException("配送地址不能为空");
        }

        // 检查地址是否存在于用户的地址列表中
        boolean addressExists = deliveryAddressRepository.findByIdAndCustomerId(
                order.getDeliveryAddress().getId(), userId).isPresent();

        if (!addressExists) {
            throw new RuntimeException("配送地址不存在或不属于当前用户");
        }

        // 3. 计算订单总金额并设置业务信息
        BigDecimal totalAmount = calculateTotalAmount(cartItems);
        Business business = businessService.findById(businessId).orElse(null);

        // 4. 设置订单信息
        order.setCustomer(userService.getUserById(userId));
        order.setBusiness(business);
        order.setOrderTotal(totalAmount);
        order.setOrderDate(LocalDateTime.now());
        order.setDeliveryAddress(order.getDeliveryAddress());
        order.setOrderState(0); // 0表示待支付状态

        // 5. 设置审计字段
        LocalDateTime now = LocalDateTime.now();
        order.setCreator(userId);
        order.setCreateTime(now);
        order.setUpdater(userId);
        order.setUpdateTime(now);
        order.setDeleted(false);

        // 6. 保存订单
        Order savedOrder = orderRepository.save(order);

        // 7. 保存订单项 - 添加商品快照信息
        for (Cart cartItem : cartItems) {
            OrderDetailet detailet = new OrderDetailet();
            detailet.setOrder(savedOrder);
            detailet.setFood(cartItem.getFood());
            detailet.setQuantity(cartItem.getQuantity());

            // 保存商品快照信息
            if (cartItem.getFood() != null) {
                Food food = cartItem.getFood();
                detailet.setFoodNameSnapshot(food.getFoodName());
                detailet.setFoodPriceSnapshot(food.getFoodPrice());
                detailet.setFoodImgSnapshot(food.getFoodImg());
                detailet.setFoodExplainSnapshot(food.getFoodExplain());
                detailet.setDeliverPrinceSnapshot(business.getDeliveryPrice());
            }

            detailet.setCreator(userId);
            detailet.setCreateTime(now);
            detailet.setUpdater(userId);
            detailet.setUpdateTime(now);
            detailet.setDeleted(false);

            orderDetailetRepository.save(detailet);
        }

        // 8. 清空购物车
        cartRepository.deleteAll(cartItems);

        return savedOrder;
    }

}